"use client";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
SheetTrigger,
SheetFooter,
} from "@/components/ui/sheet";
import { trpc } from "@/app/_trpc/client";
import { useEffect, useState } from "react";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { z } from "zod";
import { useToast } from "@/components/ui/use-toast";
import useFormHandler from "@/hooks/useFormHandler";
import Loading from "@/components/Loading";
import { projectMaterialSchema } from "@/lib/schemas/materialSchema";
import { ProjectDetail } from "@/server/project/domain/models";
import { SelectedMaterial } from "../types";
import { MdModeEdit } from "react-icons/md";
interface MaterialFormProps {
project: ProjectDetail;
isEdit?: boolean;
editValues?: SelectedMaterial;
}
const MaterialFormSidebar = ({
project,
isEdit,
editValues,
}: MaterialFormProps) => {
const utils = trpc.useUtils();
const [open, setOpen] = useState<boolean>(false);
const { toast } = useToast();
const defaultValues: z.infer<typeof projectMaterialSchema> = {
projectId: "",
requiredQuantity: 0,
projectName: "",
materialId: "",
usedQuantity: 0,
availableQuantity: 0,
};
const {
form,
isInputChanged,
setIsInputChanged,
setFormValues,
getChangedFields,
} = useFormHandler(projectMaterialSchema, defaultValues);
useEffect(() => {
if (open) {
let initialValues = {
projectId: project.id,
projectName: project.name,
};
if (isEdit && editValues) {
initialValues = { ...initialValues, ...editValues };
}
setFormValues(initialValues);
}
}, [open, project, isEdit, editValues]);
const { mutate: createProjectMaterialMutation, isPending: isPendingCreate } =
trpc.materials.addMaterialToProject.useMutation({
onSuccess: () => {
setOpen(false);
toast({
title: "Exito",
description: "Tarea actualizada con exito",
variant: "default",
});
setIsInputChanged(false);
utils.projects.getProjectById.invalidate({ value: project.id });
},
onError: (opts) => {
toast({
title: "Error",
description: opts?.message,
variant: "destructive",
});
},
});
const {
mutate: updateProjectMaterialMutation,
isPending: isPendingUpdate,
isSuccess,
} = trpc.materials.updateProjectMaterial.useMutation({
onSuccess: () => {
setOpen(false);
toast({
title: "Exito",
description: "Tarea actualizada con exito",
variant: "default",
});
setIsInputChanged(false);
utils.projects.getProjectById.invalidate({
value: editValues?.projectId!,
});
},
onError: (opts) => {
toast({
title: "Error",
description: opts?.message,
variant: "destructive",
});
},
});
const { data: materials } = trpc.materials.getMaterials.useQuery(void 0, {
refetchOnMount: false,
refetchOnWindowFocus: false,
});
const onSubmit = (values: z.infer<typeof projectMaterialSchema>) => {
let valuesCreateOrUpdate: any = values;
if (isEdit) {
const changedFields = getChangedFields(values);
valuesCreateOrUpdate = {
projectId: values.projectId,
projectName: values.projectName,
materialId: values.materialId,
...changedFields,
};
updateProjectMaterialMutation(valuesCreateOrUpdate);
return;
}
createProjectMaterialMutation(values);
};
return (
<Sheet open={open} onOpenChange={setOpen}>
<SheetTrigger>
{isEdit ? (
<MdModeEdit className="text-2xl text-blue-800 " />
) : (
<Button
variant="outline"
size="sm"
className=" rounded-full text-white bg-primary"
>
Agregar material
</Button>
)}
</SheetTrigger>
<SheetContent>
<SheetHeader>
<SheetTitle>
{isEdit ? "Actualizar material" : "Crear material"}
</SheetTitle>
<SheetDescription>
Define la cantidad de material usados cada dia.
</SheetDescription>
</SheetHeader>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<div className="grid gap-4 py-4 mt-10">
<FormField
control={form.control}
defaultValue={project.name}
name="projectName"
render={({ field }) => (
<FormItem>
<FormLabel>Projecto</FormLabel>
<FormControl>
<Input disabled placeholder="Ej: projecto" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="materialId"
render={({ field }) => (
<FormItem>
<FormLabel>Material</FormLabel>
<Select
onValueChange={field.onChange}
defaultValue={field?.value}
>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Seleccione un material" />
</SelectTrigger>
</FormControl>
<SelectContent>
{materials?.map((material) => (
<SelectItem key={material?.id} value={material?.id!}>
{material?.name}
</SelectItem>
))}
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="requiredQuantity"
render={({ field }) => (
<FormItem>
<FormLabel>Cantidad requerida</FormLabel>
<FormControl>
<Input
min={0}
type="number"
placeholder="Ej: 1"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="availableQuantity"
render={({ field }) => (
<FormItem>
<FormLabel>Cantidad disponible</FormLabel>
<FormControl>
<Input
min={0}
type="number"
placeholder="Ej: 1"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<SheetFooter>
<Button
type="submit"
disabled={!isInputChanged || isPendingCreate || isPendingUpdate}
>
<span className="mr-2">
{isPendingCreate || isPendingUpdate ? "Cargando" : isEdit ? 'Modificar' : 'Crear'}
</span>
{isPendingCreate || isPendingUpdate ? (
<Loading size={15} />
) : null}{" "}
</Button>
</SheetFooter>
</form>
</Form>
</SheetContent>
</Sheet>
);
};
export default MaterialFormSidebar;